home *** CD-ROM | disk | FTP | other *** search
/ TPUG - Toronto PET Users Group / TPUG Users Group CD / TPUG Users Group CD.iso / AMIGA / AMICUS / AMICUS04.ADF / C / freemap.c < prev    next >
C/C++ Source or Header  |  1985-10-30  |  13KB  |  536 lines

  1. /* freemap.c v29 or so */
  2.  
  3. /*** Makefile ***/
  4.  
  5. V=              /usr/commodore/amiga/V1
  6. LIB=            $(V)/internal/lib
  7. SSTART=         20000
  8. #STARTUP=       /usr/commodore/amiga/V1/internal/lib/nodos_startup.obj
  9. STARTUP=        /usr/commodore/amiga/V1/internal/lib/startup.obj
  10. # BADSTUFF=     nodos.obj txwrite.obj
  11. MAKEFILE=       makefile
  12. # MYLIBS=       $(LIB)/debug.lib $(LIB)/intuition/intuition_lib.lib
  13. MYLIBS=         $(LIB)/debug.lib
  14.  
  15. FREEMAP=        $(STARTUP) $(MYLIBS) freemap.obj
  16.  
  17. all:            freemap.ld
  18.  
  19. freemap.ld:     $(FREEMAP)
  20.                 echo >$*.with "from $(FREEMAP)"
  21.                 $(LINK) with=$*.with \
  22.                         library=${LIBDIR}/amiga.lib \
  23.                         to=$*.ld $(LFLAGS)
  24.  
  25. .INCLUDE=/usr/commodore/amiga/V1/tools/makemeta
  26.  
  27.  
  28.  
  29. /*** freemap.h ***/
  30.  
  31. /*** intuall.h **************************************************************
  32.  *
  33.  *  intuall.h, general includer for intuition
  34.  *
  35.  *  Confidential Information: Commodore-Amiga, Inc.
  36.  *  Copyright (c) Commodore-Amiga, Inc.
  37.  *
  38.  *                              Modification History
  39.  *      date        author :    Comments
  40.  *      ------      ------      -------------------------------------
  41.  *      1-30-85     -=RJ=-      created this file!
  42.  *
  43.  ****************************************************************************/
  44.  
  45. #include <exec/types.h>
  46. #include <exec/tasks.h>
  47. #include <exec/nodes.h>
  48. #include <exec/lists.h>
  49. #include <exec/libraries.h>
  50. #include <exec/ports.h>
  51. #include <exec/interrupts.h>
  52. #include <exec/io.h>
  53. #include <exec/memory.h>
  54. #include <exec/execbase.h>
  55.  
  56. /* ALWAYS INCLUDE GFX.H before any other amiga includes */
  57. #include <graphics/gfx.h>
  58.  
  59. #include <hardware/blit.h>
  60. #include <graphics/collide.h>
  61. #include <graphics/copper.h>
  62. #include <graphics/display.h>
  63. #include <hardware/dmabits.h>
  64. #include <graphics/gels.h>
  65. #include <graphics/clip.h>
  66. #include <graphics/rastport.h>
  67. #include <graphics/view.h>
  68. #include <graphics/gfxbase.h>
  69. #include <hardware/intbits.h>
  70. #include <graphics/gfxmacros.h>
  71. #include <graphics/layers.h>
  72. #include <graphics/text.h>
  73. #include <hardware/custom.h>
  74.  
  75. extern struct Custom custom;
  76.  
  77. #include <devices/timer.h>
  78. #include <devices/inputevent.h>
  79.  
  80. #include <intuition/intuition.h>
  81.  
  82.  
  83.  
  84.  
  85. /*** freemap.c ***/
  86.  
  87. /*****************************************************************************
  88.  *
  89.  * MemMap program creates a visual diagram of free memory
  90.  *
  91.  * =Robert J. Mical=
  92.  * 11 September 1985
  93.  * 
  94.  * CONFIDENTIAL and PROPRIETARY
  95.  * Copyright (C) 1985, COMMODORE-AMIGA, INC.
  96.  * All Rights Reserved
  97.  *
  98.  *
  99.  ****************************************************************************/
  100.  
  101. #include "freemap.h"
  102.  
  103. #define SCREENWIDTH     320
  104. #define SCREENHEIGHT    36
  105.  
  106. #define STARTLINE       6
  107. #define STARTCOLUMN     (2 + 4)
  108.  
  109. #define LEFTOFFSET      6
  110.  
  111. #define MENU_INFO       2
  112. #define MENU_REDISPLAY  1
  113. #define MENU_QUIT       0
  114.  
  115. #define SCREENBYTEWIDTH 40
  116. #define MAPBYTEWIDTH    32      /* must be a power of two */
  117. #define MAX_BLOCK_COUNT ((512 * 1024) >> 6)
  118. #define printf kprintf
  119.  
  120. struct IntuitionBase *IntuitionBase;
  121. struct GfxBase *GfxBase;
  122. extern struct ExecBase *SysBase;
  123.  
  124. struct TextAttr SafeFont =
  125.     {
  126.     "topaz.font",
  127.     8,
  128.     0,
  129.     0,
  130.     };
  131.  
  132.  
  133. struct IntuiText PleaseText = 
  134.     {
  135.     0, 1,
  136.     JAM2,
  137.     1, 1,
  138.     NULL,
  139.     "Please",
  140.     NULL,
  141.     };
  142.  
  143.  
  144. struct MenuItem PleaseItem =
  145.     {
  146.     NULL,
  147.     0, 0,
  148.     88, 9,
  149.     ITEMTEXT | ITEMENABLED | HIGHCOMP,
  150.     0,
  151.     &PleaseText,
  152.     NULL,
  153.     0,
  154.     NULL,
  155.     NULL,
  156.     };
  157.  
  158.  
  159. struct Menu MapMenus[] =
  160.     {
  161.         {
  162.         NULL,
  163.         10, 0,
  164.         48, 0,
  165.         MENUENABLED,
  166.         "Info",
  167.         &PleaseItem,
  168.         },
  169.  
  170.         {
  171.         &MapMenus[0],
  172.         58, 0,
  173.         88, 0,
  174.         MENUENABLED,
  175.         "Redisplay",
  176.         &PleaseItem,
  177.         },
  178.  
  179.         {
  180.         &MapMenus[1],
  181.         146, 0,
  182.         48, 0,
  183.         MENUENABLED,
  184.         "Quit",
  185.         &PleaseItem,
  186.         },
  187.  
  188.     };
  189.  
  190.  
  191. struct NewScreen MapScreen =
  192.     {
  193.     0, 200 - SCREENHEIGHT,
  194.     SCREENWIDTH, SCREENHEIGHT, 1,
  195.     0, 1,
  196.     NULL,
  197.     CUSTOMSCREEN,
  198.     &SafeFont,
  199.     NULL,
  200.     NULL,
  201.     NULL,
  202.     };
  203.  
  204.  
  205. struct NewWindow MapWindow =
  206.     {
  207.     LEFTOFFSET, 0,
  208.     (MAPBYTEWIDTH << 3) + 4, SCREENHEIGHT,
  209.     -1, -1,
  210.     MENUPICK | MENUVERIFY,
  211.     SMART_REFRESH | BACKDROP | BORDERLESS | NOCAREREFRESH,
  212.     NULL, 
  213.     NULL, 
  214.     NULL, 
  215.     NULL, 
  216.     NULL, 
  217.     0, 0, 0, 0,
  218.     CUSTOMSCREEN,
  219.     };
  220.     
  221.     
  222. struct Screen *MyScreen;
  223. struct Window *MyWindow;
  224. SHORT BitsAvailable;
  225. SHORT BlockCount;
  226. BYTE BitsValue;
  227. SHORT WidthIndex;
  228. UBYTE *MemBlock;
  229. UBYTE *MapPointer;
  230.  
  231. ShiftMask[8] =
  232.     {
  233.     0xFF,
  234.     0X01,
  235.     0x03,
  236.     0x07,
  237.     0x0F,
  238.     0x1F,
  239.     0x3F,
  240.     0x7F,
  241.     };
  242.  
  243.  
  244. RestartWindow()
  245. {
  246.     SetRast(MyWindow->RPort, 0);
  247.     Move(MyWindow->RPort, 0, 0);
  248.     Draw(MyWindow->RPort, 0, SCREENHEIGHT - 1);
  249.     Draw(MyWindow->RPort, (MAPBYTEWIDTH << 3)+4-1, SCREENHEIGHT - 1);
  250.     Draw(MyWindow->RPort, (MAPBYTEWIDTH << 3) + 4 - 1, 0);
  251.     Draw(MyWindow->RPort, 0, 0);
  252. }
  253.  
  254.  
  255. BumpMapPointer()
  256. {
  257.     WidthIndex++;
  258.     if (WidthIndex == MAPBYTEWIDTH)
  259.         {
  260.         WidthIndex = 0;
  261.         MapPointer += (SCREENBYTEWIDTH - MAPBYTEWIDTH + 1);
  262.         }
  263.     else MapPointer++;
  264. }
  265.  
  266.  
  267. ShiftInBits(bitcount)
  268. SHORT bitcount;
  269. {
  270.     SHORT shift, bytecount;
  271.  
  272.     if (BitsAvailable & 0x7)
  273.         {
  274.         /* There's less than a whole byte available, so we must start 
  275.          * by shifting.  Get the shift amount, which will be either all
  276.          * of the bits that are available, or the block count if it's less
  277.          * than the count of the available bits
  278.          */
  279.         if (bitcount > BitsAvailable) shift = BitsAvailable;
  280.         else shift = bitcount;
  281.  
  282.         /* Shift the current contents of this byte of the map 
  283.          * out of the way of our new bits.
  284.          */
  285.         *MapPointer <<= shift;
  286.         
  287.         /* The above shift shifts zero bits in from the right.
  288.          * If the current BitsValue is clear, leave them zero, else set our
  289.          * new bits.
  290.          */
  291.         if (BitsValue) *MapPointer |= ShiftMask[shift];
  292.         
  293.         /* Reduce the block count by the number of bits we just arranged */
  294.         bitcount -= shift;
  295.         
  296.         /* if we've used up this memory map byte, advance to the next one */
  297.         if ((BitsAvailable -= shift) == 0)
  298.             {
  299.             BitsAvailable = 8;
  300.             BumpMapPointer();
  301.             }
  302.  
  303.         }
  304.  
  305.     /* Now that we've taken care of any partially completed Map bytes,
  306.      * let's check for any whole bytes that we can set (speed!)
  307.      */
  308.     bytecount = bitcount >> 3;
  309.     while (bytecount)
  310.         {
  311.         *MapPointer = BitsValue;
  312.         BumpMapPointer();
  313.         bytecount--;
  314.         }
  315.  
  316.     /* Finally, do any remaining bitcount bits to be set */
  317.     if (bitcount &= 0x7)
  318.         {
  319.         *MapPointer = BitsValue;        /* Cheating, in a sense, but FAST! */
  320.         BitsAvailable = 8 - bitcount;
  321.         }
  322. }
  323.  
  324.  
  325. SHORT FindFreeBlock()
  326. {
  327.     SHORT firstwholeblock, nextrealblock;
  328.  
  329.     FOREVER
  330.         {
  331.         if (MemBlock == 0) return(0);
  332.         firstwholeblock = (MemBlock + 63) >> 6;
  333.         nextrealblock = ( MemBlock 
  334.                 + ((struct MemChunk *)MemBlock)->mc_Bytes ) >> 6;
  335.  
  336.         MemBlock = ((struct MemChunk *)MemBlock)->mc_Next;
  337.  
  338.         if (firstwholeblock < nextrealblock)
  339.             {
  340.             BlockCount = nextrealblock - firstwholeblock;
  341.             return(firstwholeblock);
  342.             }
  343.         }
  344. }
  345.  
  346.  
  347.  
  348. SetTimer(sec, micro, timermsg)
  349. ULONG sec, micro;
  350. struct IOStdReq *timermsg;
  351. {
  352.     timermsg->io_Command = TR_ADDREQUEST;    /* add a new timer request */
  353.     timermsg->io_Actual = sec;    /* seconds */
  354.     timermsg->io_Length = micro;    /* microseconds */
  355.     SendIO(timermsg);   /* post a request to the timer */
  356. }
  357.  
  358.  
  359.  
  360. main()
  361. {
  362.     SHORT i, j;
  363.     struct MsgPort *timerport;
  364.     struct IOStdReq *timermsg;
  365.     struct MemHeader *MemHeader;
  366.     SHORT NextFreeBlock, NextTakenBlock;
  367.     ULONG wakeupbits, timerbit, windowbit;
  368.     struct IntuiMessage *message;
  369.     ULONG class;
  370.     USHORT code;
  371.     BOOL Redisplay;
  372.  
  373.  
  374.     if ((IntuitionBase = (LONG *)OpenLibrary("intuition.library", 0)) == 0)
  375.         {
  376.         printf("NO LIBRARY");
  377.         goto EXITING;
  378.         }
  379.  
  380.     if ((GfxBase = (LONG *)OpenLibrary("graphics.library", 0)) == 0)
  381.         {
  382.         printf("NO LIBRARY");
  383.         goto EXITING;
  384.         }
  385.  
  386.     if ((MyScreen = (struct Screen *)OpenScreen(&MapScreen)) == NULL)
  387.         {
  388.         printf("NO SCREEN");
  389.         goto EXITING;
  390.         }
  391.  
  392.     ShowTitle(MyScreen, FALSE);
  393.     SetRGB4(&MyScreen->ViewPort, 0, 15, 12, 8);
  394.     SetRGB4(&MyScreen->ViewPort, 1, 8, 0, 0);
  395.  
  396.     MapWindow.Screen = MyScreen;        
  397.     if ((MyWindow = (struct Window *)OpenWindow(&MapWindow)) == NULL)
  398.         {
  399.         printf("NO WINDOW");
  400.         goto EXITING;
  401.         }
  402.     SetMenuStrip(MyWindow, &MapMenus[2]);
  403.     SetFont(MyWindow->RPort, OpenFont(&SafeFont));
  404.  
  405.     Move(&MyScreen->RastPort, (MAPBYTEWIDTH << 3) + 8 + 4, 18);
  406.     Text(&MyScreen->RastPort, "512K", 4);
  407.     Move(&MyScreen->RastPort, (MAPBYTEWIDTH << 3) + 8 + 4, 26);
  408.     Text(&MyScreen->RastPort, "MEMORY", 6);
  409.     Move(&MyScreen->RastPort, (MAPBYTEWIDTH << 3) + 8 + 4, 34);
  410.     Text(&MyScreen->RastPort, "MAP", 3);
  411.     RestartWindow();
  412.  
  413.     timerport = (struct MsgPort *)CreatePort(0, 0);
  414.     if (timerport == 0) goto EXITING;
  415.  
  416.     timermsg = (struct IOStdReq *)CreateStdIO(timerport);
  417.     if (timermsg == 0) goto EXITING;
  418.  
  419.     if (OpenDevice(TIMERNAME, UNIT_VBLANK, timermsg, 0) != 0)
  420.         goto EXITING;
  421.     
  422.     timerbit = 1 << timerport->mp_SigBit;
  423.     windowbit = 1 << MyWindow->UserPort->mp_SigBit;
  424.  
  425.     SetTimer(2, 0, timermsg);
  426.  
  427.     Redisplay = TRUE;
  428.  
  429.     FOREVER
  430.         {
  431.         if (Redisplay)
  432.             {
  433.             MapPointer = MyScreen->RastPort.BitMap->Planes[0];
  434.             MapPointer += (SCREENBYTEWIDTH * 2 + 1);
  435.  
  436.             Forbid();
  437.  
  438.             do
  439.                 MemHeader = (struct MemHeader *)SysBase->MemList.lh_Head;
  440.             while ((MemHeader->mh_Attributes & MEMF_CHIP) == 0);
  441.  
  442.             MemBlock = (UBYTE *)MemHeader->mh_First;
  443.         
  444.             BitsAvailable = 8;
  445.             WidthIndex = 0;
  446.             NextTakenBlock = 0;
  447.  
  448.             do 
  449.                 {
  450.                 if (NextFreeBlock = FindFreeBlock())
  451.                     {
  452.                     BitsValue = 0;
  453.                     ShiftInBits(NextFreeBlock - NextTakenBlock);
  454.                     BitsValue = -1;
  455.                     ShiftInBits(BlockCount);
  456.                     NextTakenBlock = NextFreeBlock + BlockCount;
  457.                     }
  458.                 else ShiftInBits(MAX_BLOCK_COUNT - NextTakenBlock);
  459.                 }
  460.             while (MemBlock);
  461.  
  462.             if (NextTakenBlock < MAX_BLOCK_COUNT)
  463.                 {
  464.                 BitsValue = 0;
  465.                 ShiftInBits(MAX_BLOCK_COUNT - NextTakenBlock);
  466.                 }
  467.             Permit();
  468.             }
  469.  
  470.         wakeupbits = Wait(timerbit | windowbit);
  471.  
  472.         if (wakeupbits & timerbit)
  473.             {
  474.             GetMsg(timerport);  /* this does nothing more than "clear" */
  475.             SetTimer(2, 0, timermsg);
  476.             }
  477.  
  478.         if (wakeupbits & windowbit)
  479.             {
  480.             message = (struct IntuiMessage *)GetMsg(MyWindow->UserPort);
  481.             class = message->Class;
  482.             code = message->Code;
  483.             ReplyMsg(message);
  484.             switch (class)
  485.                 {
  486.                 case MENUVERIFY:
  487.                     Redisplay = FALSE;
  488.                     break;
  489.                 case MENUPICK:
  490.                     switch (MENUNUM(code))
  491.                         {
  492.                         case MENU_INFO:
  493.                             RestartWindow();
  494.                             Move(MyWindow->RPort, 
  495.                                     STARTCOLUMN, STARTLINE);
  496.                             Text(MyWindow->RPort,
  497.                                     "Each pixel represents 64 bytes.", 31);
  498.                             Move(MyWindow->RPort, 
  499.                                     STARTCOLUMN + 20, STARTLINE + 9);
  500.                             Text(MyWindow->RPort,
  501.                                     "If all bytes are free, the", 26);
  502.                             Move(MyWindow->RPort, 
  503.                                     STARTCOLUMN, STARTLINE + 18);
  504.                             Text(MyWindow->RPort,
  505.                                     "pixel is dark, else it's light.", 31);
  506.                             Move(MyWindow->RPort, 
  507.                                     STARTCOLUMN + 20, STARTLINE + 28);
  508.                             Text(MyWindow->RPort,
  509.                                     "This trinket by  =RJMical=", 26);
  510.                             break;
  511.                         case MENU_REDISPLAY:
  512.                             RestartWindow();
  513.                         case NOMENU:
  514.                             Redisplay = TRUE;
  515.                             break;
  516.                         case MENU_QUIT:
  517.                             goto EXITING;
  518.                         }
  519.                 }
  520.             }
  521.         }
  522.  
  523. EXITING:
  524.     if (MyWindow) CloseWindow(MyWindow);
  525.     if (MyScreen) CloseScreen(MyScreen);
  526.     if (timerport)
  527.         {
  528.         Wait(timerbit);
  529.         GetMsg(timerport);
  530.  
  531.         CloseDevice(timermsg);
  532.         DeleteStdIO(timermsg);
  533.         DeletePort(timerport);
  534.         }
  535. }
  536.